using Engine.Graphics.VertexStructures;
using SharpDX;
using SharpDX.Direct3D11;

namespace ModelViewer.GraphicObjects
{
    internal class NodeMesh
    {
        #region Private Fields

        private Engine.Engine engine;
        private Buffer ib;
        private BufferDescription indexBufferDescription;
        private float size = 50.5f;
        private Buffer vb;
        private VertexBufferBinding vertexBufferBinding;
        private BufferDescription vertexBufferDescription;
        private CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[2];

        /// <summary>
        /// The size above the ground
        /// </summary>
        private float yOffset = 1.0f;

        #endregion Private Fields

        #region Public Constructors

        public NodeMesh(Engine.Engine device, Vector3 Position, System.Drawing.Color color)
        {
            this.engine = device;
            vertices = new CustomVertex.PositionColored[4];
            short[] indices = new short[] { 0, 1, 2, 3 };

            Position.Y += yOffset;

            Vector3 temp = new Vector3();
            temp.X = Position.X - size;
            temp.Y = Position.Y;
            temp.Z = Position.Z;
            vertices[0].Position = temp;
            vertices[0].Color = new Color4(color.ToArgb());

            temp.X = Position.X + size;
            temp.Y = Position.Y;
            temp.Z = Position.Z;
            vertices[1].Position = temp;
            vertices[1].Color = new Color4(color.ToArgb());

            temp.X = Position.X;
            temp.Y = Position.Y;
            temp.Z = Position.Z - size;
            vertices[2].Position = temp;
            vertices[2].Color = new Color4(color.ToArgb());

            temp.X = Position.X;
            temp.Y = Position.Y;
            temp.Z = Position.Z + size;
            vertices[3].Position = temp;
            vertices[3].Color = new Color4(color.ToArgb());

            vertexBufferDescription = new BufferDescription()
            {
                BindFlags = BindFlags.VertexBuffer,
                CpuAccessFlags = 0,
                // OptionFlags = ResourceOptionFlags.BufferStructured,
                SizeInBytes = CustomVertex.PositionColored.SizeInBytes() * vertices.Length,
                Usage = ResourceUsage.Default
            };
            indexBufferDescription = new BufferDescription()
            {
                BindFlags = BindFlags.IndexBuffer,
                CpuAccessFlags = 0,
                SizeInBytes = indices.Length * sizeof(short),
                Usage = ResourceUsage.Default,
                OptionFlags = ResourceOptionFlags.None
            };

            vb = Buffer.Create(device.Device, vertices, this.vertexBufferDescription);
            ib = Buffer.Create(device.Device, indices, this.indexBufferDescription);
        }

        #endregion Public Constructors

        #region Public Methods

        public void Dispose()
        {
            if (vb != null)
            {
                vb.Dispose();
            }
            if (ib != null)
            {
                ib.Dispose();
            }
        }

        public void Draw()
        {
            DeviceContext deviceContext = this.engine.Device.ImmediateContext;
            lock (deviceContext)
            {
                this.engine.Grafic.ShaderManager[0].SetShader(this.engine.Grafic.ShaderManager[0].ColorShader);
                deviceContext.InputAssembler.SetVertexBuffers(0, this.vertexBufferBinding);
                deviceContext.InputAssembler.SetIndexBuffer(this.ib, SharpDX.DXGI.Format.R16_UInt, 0);
                deviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
                deviceContext.DrawIndexed(6, 0, 0);
            }
        }

        public void UpdatePosition(Vector3 Position)
        {
            Position.Y += yOffset;
            Vector3 temp = new Vector3();
            temp.X = Position.X - size;
            temp.Y = Position.Y;
            temp.Z = Position.Z;
            vertices[0].Position = temp;
            //vertices[0].Color = color.ToArgb();

            temp.X = Position.X + size;
            temp.Y = Position.Y;
            temp.Z = Position.Z;
            vertices[1].Position = temp;
            //vertices[1].Color = color.ToArgb();

            temp.X = Position.X;
            temp.Y = Position.Y;
            temp.Z = Position.Z - size;
            vertices[2].Position = temp;
            //vertices[2].Color = color.ToArgb();

            temp.X = Position.X;
            temp.Y = Position.Y;
            temp.Z = Position.Z + size;
            vertices[3].Position = temp;

            vb = Buffer.Create(engine.Device, vertices, this.vertexBufferDescription);
            this.vertexBufferBinding = new VertexBufferBinding(this.vb, CustomVertex.PositionColored.SizeInBytes(), 0);
        }

        #endregion Public Methods
    }
}